home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 80 / CD Actual 80 Julio-Agosto 2003.iso / Linux / LinuxGazette / lg / issue47 / misc / makarov / input.d < prev    next >
Encoding:
Text File  |  2002-08-14  |  1.8 KB  |  56 lines

  1. include "ir";
  2.  
  3. func get_ir (f) {
  4.   var ln, lno = 0, code, lab, op, v;
  5.   // Patterns
  6.   var p_sp = "[ \t]*";
  7.   var p_code = p_sp @ "(goto|skipif|gosub|match|return|next)";
  8.   var p_id = "[a-zA-Z][a-zA-Z0-9]*";
  9.   var p_lab = p_sp @ "((" @ p_id @ "):)?";
  10.   var p_str = "\"[^\"]*\"";
  11.   var p_op = p_sp @ "(" @ p_id @ "|" @ p_str @ ")?";
  12.   var p_comment = p_sp @ "(;.*)?";
  13.   var pattern = "^" @ p_lab @ "(" @ p_code @ p_op @ ")?" @ p_comment @ "$";
  14.  
  15.   var pr = ir ();
  16.   try {
  17.     for (;;) {
  18.       ln = fgetln (f);
  19.       lno++;
  20.       v = match (pattern, ln);
  21.       if (v == nil)
  22.     err ("syntax error on line ", lno);
  23.       lab = (v[4] >= 0 ? subv (ln, v[4], v[5] - v[4]) : nil);
  24.       if (!(#pr.ns in pr.i2l))
  25.         pr.i2l {#pr.ns} = [];
  26.       if (lab != nil) {
  27.     if (lab in pr.l2i)
  28.       err ("redefinition lab ", lab, " on line ", lno);
  29.     pr.l2i {lab} = #pr.ns;
  30.         ins (pr.i2l {#pr.ns}, lab, -1);
  31.       }
  32.       code = (v[8] >= 0 ? subv (ln, v[8], v[9] - v[8]) : nil);
  33.       if (code == nil)
  34.         continue;  // skip comment or absent code
  35.       op = (v[10] >= 0 ? subv (ln, v[10], v[11] - v[10]) : nil);
  36.       var node = irn (lno);
  37.       if (code == "goto" || code == "gosub") {
  38.     if (op == nil || match (p_id, op) == nil)
  39.       err ("invalid or absent lab `", op, "' on line ", lno);
  40.     node = (code == "goto" ? node.goto (op) :  node.gosub (op));
  41.       } else if (code == "skipif" || code == "match") {
  42.     if (op == nil || match (p_id, op) == nil)
  43.       err ("invalid or absent name `", op, "' on line ", lno);
  44.     node = (code == "skipif" ? node.skipif (op) : node.match (op));
  45.       } else if (code == "return" || code == "next") {
  46.     if (op != nil)
  47.       err (" non empty operand `", op, "' on line ", lno);
  48.     node = (code == "next" ? node.next (op) : node.ret ());
  49.       }
  50.       ins (pr.ns, node, -1);
  51.     }
  52.   } catch (invcalls.eof) {
  53.   }
  54.   return pr;
  55. }
  56.